package com.lmt.service.impl;

import com.lmt.base.BaseService;
import com.lmt.base.ResultData;
import com.lmt.entity.Classify;
import com.lmt.entity.search.ClassifySearch;
import com.lmt.repository.ClassifyRepository;
import com.lmt.service.ClassifyService;
import com.lmt.util.RedisCacheUtil;
import com.lmt.util.ResultUtil;
import com.lmt.util.SystemConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * Date 2018/07/17
 *
 * @author MT-Lin
 */
@Service("ClassifyServiceImpl")
public class ClassifyServiceImpl extends BaseService implements ClassifyService {

	private final ClassifyRepository classifyRepository;

	private final RedisCacheUtil redisCacheUtil;

	@Autowired
	public ClassifyServiceImpl(ClassifyRepository classifyRepository, RedisCacheUtil redisCacheUtil) {
		this.classifyRepository = classifyRepository;
		this.redisCacheUtil = redisCacheUtil;
	}

	@Override
	public ResultData getParentTree(String classifyType) {
		List result = this.getOptions(classifyType);
		return ResultUtil.newSuccess("成功获取父节点选择树", result);
	}

	@Override
	public ResultData save(Classify classify) {
		Classify existClassify = this.classifyRepository.findByClassifyTypeAndDesignationAndParentId(
				classify.getClassifyType(), classify.getDesignation(), classify.getParentId());
		if (null != existClassify) {
			return ResultUtil.newFail("父类中已存在该名称或者添加的分类类型中已存在该名称");
		}
		classify.setCreator(redisCacheUtil.getUserName(classify));
		this.classifyRepository.save(classify);
		if (null == classify.getId()) {
			return ResultUtil.newFail("添加分类失败");
		}
		return ResultUtil.newSuccess("添加分类成功");
	}

	@Override
	public ResultData search(ClassifySearch classifySearch) {
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT c.id, c.designation, c.description, c.creator, ");
		sql.append("c.collection_num AS collectionNum, ");
		sql.append("c.download_num AS downloadNum, ");
		sql.append("c.upload_num AS uploadNum, ");
		sql.append("c.gmt_create AS gmtCreate, ");
		sql.append("(SELECT tc.designation FROM classify AS tc WHERE tc.id = c.parent_id) ");
		sql.append("AS parent, ");
		sql.append("(SELECT dd.designation FROM digital_dictionary AS dd WHERE dd.code = c.classify_type) ");
		sql.append("AS classifyType ");
		sql.append("FROM classify AS c WHERE 1=1 ");
		if (!StringUtils.isEmpty(classifySearch.getKeyword())) {
			sql.append("AND (c.designation LIKE ? OR c.description LIKE ? OR c.creator LIKE ?) ");
			classifySearch.setParamsCount(3);
		}
		Map<String, Object> result = this.paginationSearch(sql, classifySearch);
		return ResultUtil.newSuccess("查询成功", result);
	}

	@Override
	public ResultData findOneById(String id) {
		Optional<Classify> result = this.classifyRepository.findById(id);
		if (!result.isPresent()) {
			return ResultUtil.newFail("该分类不存在");
		}

		return ResultUtil.newSuccess("查询成功", result.get());
	}

	@Override
	public ResultData update(Classify classify) {
		Optional<Classify> old = this.classifyRepository.findById(classify.getId());
		if (!old.isPresent()) {
			ResultUtil.newFail("修改的分类不存在");
		}
		this.classifyRepository.save(classify);
		return ResultUtil.newSuccess("修改成功");
	}

	@Override
	public ResultData delete(List<Classify> classifies) {
		for (Classify classify : classifies) {
			this.classifyRepository.deleteById(classify.getId());
		}
		return ResultUtil.newSuccess("删除成功");
	}

	/**
	 * @apiNote 获取选择项的数据
	 * @param classifyType 分类类型
	 * @return List
	 */
	private List getOptions(String classifyType) {
		List<Map<String, Object>> result = new ArrayList<>();
		List<Classify> firstLevel = new ArrayList<>();
		List<Classify> children = new ArrayList<>();
		List<String> parentId = new ArrayList<>();
		List<Classify> all = this.classifyRepository.findByClassifyType(classifyType);
		Map<String, Map<String, Object>> temp = new HashMap<>(all.size());
		for (Classify classify : all) {
			Map<String, Object> tempOption = new HashMap<>(6);
			tempOption.put(SystemConstant.PROPS_VALUE, classify.getId());
			tempOption.put(SystemConstant.PROPS_ID, classify.getId());
			tempOption.put(SystemConstant.PROPS_LABEL, classify.getDesignation());
			tempOption.put(SystemConstant.PROPS_CHILDREN, new ArrayList<>());
			temp.put(classify.getId(), tempOption);
			if (classify.getParentId() != null) {
				parentId.add(classify.getParentId());
			}
			if (null == classify.getParentId()) {
				firstLevel.add(classify);
			} else {
				children.add(classify);
			}
		}
		for (Classify child : children) {
			//noinspection unchecked
			((List) temp.get(child.getParentId()).get(SystemConstant.PROPS_CHILDREN)).add(temp.get(child.getId()));
			if (!parentId.contains(child.getId())) {
				temp.get(child.getId()).remove(SystemConstant.PROPS_CHILDREN);
			}
		}
		for (Classify classify : firstLevel) {
			result.add(temp.get(classify.getId()));
		}
		return result;
	}

}
